home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 97 / CD-ROM 97 / CD-ROM 97.iso / internet / ghostzilla / ghsetup.exe / chrome / comm.jar / content / editor / EdTableProps.js < prev    next >
Encoding:
JavaScript  |  2002-04-09  |  38.0 KB  |  1,298 lines

  1. /*
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  *
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  *
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *    Ben Goodger
  22.  */
  23.  
  24. //Cancel() is in EdDialogCommon.js
  25. var tagname = "table"
  26. var TableElement;
  27. var CellElement;
  28. var TableCaptionElement;
  29. var globalCellElement;
  30. var globalTableElement
  31. const TablePanel = 0;
  32. const CellPanel = 1;
  33. var currentPanel = TablePanel;
  34. var validatePanel;
  35. const defHAlign =   "left";
  36. const centerStr =   "center";  //Index=1
  37. const rightStr =    "right";   // 2
  38. const justifyStr =  "justify"; // 3
  39. const charStr =     "char";    // 4
  40. const defVAlign =   "middle";
  41. const topStr =      "top";
  42. const bottomStr =   "bottom";
  43. var bgcolor = "bgcolor";
  44. var TableColor;
  45. var CellColor;
  46.  
  47. const cssBackgroundColorStr = "background-color";
  48.  
  49. var rowCount = 1;
  50. var colCount = 1;
  51. var lastRowIndex;
  52. var lastColIndex;
  53. var newRowCount;
  54. var newColCount;
  55. var curRowIndex;
  56. var curColIndex;
  57. var curColSpan;
  58. var SelectedCellsType = 1;
  59. var SELECT_CELL = 1;
  60. var SELECT_ROW = 2;
  61. var SELECT_COLUMN = 3;
  62. var RESET_SELECTION = 0;
  63. var cellData = new Object;
  64. var AdvancedEditUsed;
  65. var alignWasChar = false;
  66.  
  67. /*
  68. From C++:
  69.  0 TABLESELECTION_TABLE
  70.  1 TABLESELECTION_CELL   There are 1 or more cells selected
  71.                           but complete rows or columns are not selected
  72.  2 TABLESELECTION_ROW    All cells are in 1 or more rows
  73.                           and in each row, all cells selected
  74.                           Note: This is the value if all rows (thus all cells) are selected
  75.  3 TABLESELECTION_COLUMN All cells are in 1 or more columns
  76. */
  77.  
  78. var gSelectedCellCount = 0;
  79. var ApplyUsed = false;
  80. // What should these be?
  81. var maxRows    = 1000; // This is the value gecko code uses for maximum rowspan, colspan
  82. var maxColumns = 1000;
  83. var selection;
  84. var CellDataChanged = false;
  85. var canDelete = false;
  86. var gPrefs = GetPrefs();
  87. var gUseCSS = true;
  88.  
  89. // dialog initialization code
  90. function Startup()
  91. {
  92.   if (!InitEditorShell()) return;
  93.  
  94.   selection = editorShell.editorSelection;
  95.   if (!selection) return;
  96.  
  97.   // Get dialog widgets - Table Panel
  98.   gDialog.TableRowsInput = document.getElementById("TableRowsInput");
  99.   gDialog.TableColumnsInput = document.getElementById("TableColumnsInput");
  100.   gDialog.TableWidthInput = document.getElementById("TableWidthInput");
  101.   gDialog.TableWidthUnits = document.getElementById("TableWidthUnits");
  102.   gDialog.TableHeightInput = document.getElementById("TableHeightInput");
  103.   gDialog.TableHeightUnits = document.getElementById("TableHeightUnits");
  104.   if (!gPrefs.getBoolPref("editor.use_css") || (editorShell.editorType != "html"))
  105.   {
  106.     gUseCSS = false;
  107.     var tableHeightLabel = document.getElementById("TableHeightLabel");
  108.     tableHeightLabel.parentNode.removeChild(tableHeightLabel);
  109.     gDialog.TableHeightInput.parentNode.removeChild(gDialog.TableHeightInput);
  110.     gDialog.TableHeightUnits.parentNode.removeChild(gDialog.TableHeightUnits);
  111.   }
  112.   gDialog.BorderWidthInput = document.getElementById("BorderWidthInput");
  113.   gDialog.SpacingInput = document.getElementById("SpacingInput");
  114.   gDialog.PaddingInput = document.getElementById("PaddingInput");
  115.   gDialog.TableAlignList = document.getElementById("TableAlignList");
  116.   gDialog.TableCaptionList = document.getElementById("TableCaptionList");
  117.   gDialog.TableInheritColor = document.getElementById("TableInheritColor");
  118.  
  119.   // Cell Panel
  120.   gDialog.SelectionList = document.getElementById("SelectionList");
  121.   gDialog.PreviousButton = document.getElementById("PreviousButton");
  122.   gDialog.NextButton = document.getElementById("NextButton");
  123.   // Currently, we always apply changes and load new attributes when changing selection
  124.   // (Let's keep this for possible future use)
  125.   //gDialog.ApplyBeforeMove =  document.getElementById("ApplyBeforeMove");
  126.   //gDialog.KeepCurrentData = document.getElementById("KeepCurrentData");
  127.  
  128.   gDialog.CellHeightInput = document.getElementById("CellHeightInput");
  129.   gDialog.CellHeightUnits = document.getElementById("CellHeightUnits");
  130.   gDialog.CellWidthInput = document.getElementById("CellWidthInput");
  131.   gDialog.CellWidthUnits = document.getElementById("CellWidthUnits");
  132.   gDialog.CellHAlignList = document.getElementById("CellHAlignList");
  133.   gDialog.CellVAlignList = document.getElementById("CellVAlignList");
  134.   gDialog.CellInheritColor = document.getElementById("CellInheritColor");
  135.   gDialog.CellStyleList = document.getElementById("CellStyleList");
  136.   gDialog.TextWrapList = document.getElementById("TextWrapList");
  137.  
  138.   // In cell panel, user must tell us which attributes to apply via checkboxes,
  139.   //  else we would apply values from one cell to ALL in selection
  140.   //  and that's probably not what they expect!
  141.   gDialog.CellHeightCheckbox = document.getElementById("CellHeightCheckbox");
  142.   gDialog.CellWidthCheckbox = document.getElementById("CellWidthCheckbox");
  143.   gDialog.CellHAlignCheckbox = document.getElementById("CellHAlignCheckbox");
  144.   gDialog.CellVAlignCheckbox = document.getElementById("CellVAlignCheckbox");
  145.   gDialog.CellStyleCheckbox = document.getElementById("CellStyleCheckbox");
  146.   gDialog.TextWrapCheckbox = document.getElementById("TextWrapCheckbox");
  147.   gDialog.CellColorCheckbox = document.getElementById("CellColorCheckbox");
  148.   gDialog.TableTab = document.getElementById("TableTab");
  149.   gDialog.CellTab = document.getElementById("CellTab");
  150.   gDialog.TabPanels = document.getElementById("TabPanels");
  151.  
  152.   TableElement = editorShell.GetElementOrParentByTagName("table", null);
  153.   if(!TableElement)
  154.   {
  155.     dump("Failed to get table element!\n");
  156.     window.close();
  157.     return;
  158.   }
  159.   globalTableElement = TableElement.cloneNode(false);
  160.  
  161.   var tagNameObj = new Object;
  162.   var countObj = new Object;
  163.   var tableOrCellElement = editorShell.GetSelectedOrParentTableElement(tagNameObj, countObj);
  164.   gSelectedCellCount = countObj.value;
  165.  
  166.   if (tagNameObj.value == "td")
  167.   {
  168.     // We are in a cell
  169.     CellElement = tableOrCellElement;
  170.     globalCellElement = CellElement.cloneNode(false);
  171.  
  172.     // Tells us whether cell, row, or column is selected
  173.     SelectedCellsType = editorShell.GetSelectedCellsType(TableElement);
  174.  
  175.     // Ignore types except Cell, Row, and Column
  176.     if (SelectedCellsType < SELECT_CELL || SelectedCellsType > SELECT_COLUMN)
  177.       SelectedCellsType = SELECT_CELL;
  178.  
  179.     // Be sure at least 1 cell is selected.
  180.     // (If the count is 0, then we were inside the cell.)
  181.     if (gSelectedCellCount == 0)
  182.       DoCellSelection();
  183.  
  184.     // Get location in the cell map
  185.     curRowIndex = editorShell.GetRowIndex(CellElement);
  186.     curColIndex = editorShell.GetColumnIndex(CellElement);
  187.  
  188.     // We save the current colspan to quickly
  189.     //  move selection from from cell to cell
  190.     if (GetCellData(curRowIndex, curColIndex))
  191.       curColSpan = cellData.colSpan;
  192.  
  193.     // Starting TabPanel name is passed in
  194.     if (window.arguments[1] == "CellPanel")
  195.     {
  196.       currentPanel = CellPanel;
  197.  
  198.       //Set index for starting panel on the <tabpanels> element
  199.       gDialog.TabPanels.selectedIndex = CellPanel; // setAttribute("selectedIndex", CellPanel);
  200.  
  201.       // Trigger setting of style for the tab widgets
  202.       gDialog.CellTab.selected = "true";
  203.       gDialog.TableTab.selected = null;
  204.  
  205.       // Use cell element for Advanced Edit dialog
  206.       globalElement = globalCellElement;
  207.     }
  208.   }
  209.  
  210.   if (currentPanel == TablePanel)
  211.   {
  212.     // Use table element for Advanced Edit dialog
  213.     globalElement = globalTableElement;
  214.  
  215.     // We may call this with table selected, but no cell,
  216.     //  so disable the Cell Properties tab
  217.     if(!CellElement)
  218.     {
  219.       // XXX: Disabling of tabs is currently broken, so for
  220.       //      now we'll just remove the tab completely.
  221.       //CellTab.setAttribute("disabled", "true");
  222.       gDialog.CellTab.parentNode.removeChild(gDialog.CellTab);
  223.     }
  224.   }
  225.  
  226.   doSetOKCancel(onAccept, onCancel, 0, onApply);
  227.  
  228.   // Note: we must use TableElement, not globalTableElement for these,
  229.   //  thus we should not put this in InitDialog.
  230.   // Instead, monitor desired counts with separate globals
  231.   rowCount = editorShell.GetTableRowCount(TableElement);
  232.   lastRowIndex = rowCount-1;
  233.   colCount = editorShell.GetTableColumnCount(TableElement);
  234.   lastColIndex = colCount-1;
  235.  
  236.  
  237.   // Set appropriate icons and enable state for the Previous/Next buttons
  238.   SetSelectionButtons();
  239.  
  240.   // If only one cell in table, disable change-selection widgets
  241.   if (rowCount == 1 && colCount == 1)
  242.     gDialog.SelectionList.setAttribute("disabled", "true");
  243.  
  244.   // User can change these via textboxes
  245.   newRowCount = rowCount;
  246.   newColCount = colCount;
  247.  
  248.   // This flag is used to control whether set check state
  249.   //  on "set attribute" checkboxes
  250.   // (Advanced Edit dialog use calls  InitDialog when done)
  251.   AdvancedEditUsed = false;
  252.   InitDialog();
  253.   AdvancedEditUsed = true;
  254.  
  255.   // If first initializing, we really aren't changing anything
  256.   CellDataChanged = false;
  257.  
  258.   if (currentPanel == CellPanel)
  259.     setTimeout("gDialog.SelectionList.focus()", 0);
  260.   else
  261.     SetTextboxFocus(gDialog.TableRowsInput);
  262.  
  263.   SetWindowLocation();
  264. }
  265.  
  266.  
  267. function InitDialog()
  268. {
  269. // turn on Button3 to be "apply"
  270.   var applyButton = document.getElementById("Button3");
  271.   if (applyButton)
  272.   {
  273.     applyButton.label = GetString("Apply");
  274.     applyButton.removeAttribute("collapsed");
  275.   }
  276.   
  277.   // Get Table attributes
  278.   gDialog.TableRowsInput.value = rowCount;
  279.   gDialog.TableColumnsInput.value = colCount;
  280.   gDialog.TableWidthInput.value = InitPixelOrPercentMenulist(globalTableElement, TableElement, "width", "TableWidthUnits", gPercent);
  281.   if (gUseCSS) {
  282.     gDialog.TableHeightInput.value = InitPixelOrPercentMenulist(globalTableElement, TableElement, "height",
  283.                                                                 "TableHeightUnits", gPercent);
  284.   }
  285.   gDialog.BorderWidthInput.value = globalTableElement.border;
  286.   gDialog.SpacingInput.value = globalTableElement.cellSpacing;
  287.   gDialog.PaddingInput.value = globalTableElement.cellPadding;
  288.  
  289.   var marginLeft  = GetHTMLOrCSSStyleValue(globalTableElement, "align", "margin-left");
  290.   var marginRight = GetHTMLOrCSSStyleValue(globalTableElement, "align", "margin-right");
  291.   var halign = marginLeft.toLowerCase() + " " + marginRight.toLowerCase();
  292.   if (halign == "center center" || halign == "auto auto")
  293.     gDialog.TableAlignList.selectedIndex = 1;
  294.   else if (halign == "right right" || halign == "auto 0px")
  295.     gDialog.TableAlignList.selectedIndex = 2;
  296.   else // Default = left
  297.     gDialog.TableAlignList.selectedIndex = 0;
  298.  
  299.   // Be sure to get caption from table in doc, not the copied "globalTableElement"
  300.   TableCaptionElement = TableElement.caption;
  301.   var index = 0;
  302.   if (TableCaptionElement)
  303.   {
  304.     // Note: Other possible values are "left" and "right",
  305.     //  but "align" is deprecated, so should we even support "botton"?
  306.     if (GetHTMLOrCSSStyleValue(TableCaptionElement, "align", "caption-side") == "bottom")
  307.       index = 2;
  308.     else
  309.       index = 1;
  310.   }
  311.   gDialog.TableCaptionList.selectedIndex = index;
  312.  
  313.   TableColor = GetHTMLOrCSSStyleValue(globalTableElement, bgcolor, cssBackgroundColorStr);
  314.   TableColor = ConvertRGBColorIntoHEXColor(TableColor);
  315.   SetColor("tableBackgroundCW", TableColor);
  316.  
  317.   InitCellPanel();
  318. }
  319.  
  320. function InitCellPanel()
  321. {
  322.   // Get cell attributes
  323.   if (globalCellElement)
  324.   {
  325.     // This assumes order of items is Cell, Row, Column
  326.     gDialog.SelectionList.selectedIndex = SelectedCellsType-1;
  327.  
  328.     var previousValue = gDialog.CellHeightInput.value;
  329.     gDialog.CellHeightInput.value = InitPixelOrPercentMenulist(globalCellElement, CellElement, "height", "CellHeightUnits", gPixel);
  330.     gDialog.CellHeightCheckbox.checked = AdvancedEditUsed && previousValue != gDialog.CellHeightInput.value;
  331.  
  332.     previousValue= gDialog.CellWidthInput.value;
  333.     gDialog.CellWidthInput.value = InitPixelOrPercentMenulist(globalCellElement, CellElement, "width", "CellWidthUnits", gPixel);
  334.     gDialog.CellWidthCheckbox.checked = AdvancedEditUsed && previousValue != gDialog.CellWidthInput.value;
  335.  
  336.     var previousIndex = gDialog.CellVAlignList.selectedIndex;
  337.     var valign = globalCellElement.vAlign.toLowerCase();
  338.     if (valign == topStr)
  339.       gDialog.CellVAlignList.selectedIndex = 0;
  340.     else if (valign == bottomStr)
  341.       gDialog.CellVAlignList.selectedIndex = 2;
  342.     else // Default = middle
  343.       gDialog.CellVAlignList.selectedIndex = 1;
  344.  
  345.     gDialog.CellVAlignCheckbox.checked = AdvancedEditUsed && previousValue != gDialog.CellVAlignList.selectedIndex;
  346.  
  347.  
  348.     previousIndex = gDialog.CellHAlignList.selectedIndex;
  349.  
  350.     alignWasChar = false;
  351.  
  352.     var halign = GetHTMLOrCSSStyleValue(globalCellElement, "align", "text-align").toLowerCase();
  353.     switch (halign)
  354.     {
  355.       case centerStr:
  356.         gDialog.CellHAlignList.selectedIndex = 1;
  357.         break;
  358.       case rightStr:
  359.         gDialog.CellHAlignList.selectedIndex = 2;
  360.         break;
  361.       case justifyStr:
  362.         gDialog.CellHAlignList.selectedIndex = 3;
  363.         break;
  364.       case charStr:
  365.         // We don't support UI for this because layout doesn't work: bug 2212.
  366.         // Remember that's what they had so we don't change it
  367.         //  unless they change the alignment by using the menulist
  368.         alignWasChar = true;
  369.         // Fall through to use show default alignment in menu
  370.       default:
  371.         // Default depends on cell type (TH is "center", TD is "left")
  372.         gDialog.CellHAlignList.selectedIndex =
  373.           (globalCellElement.nodeName.toLowerCase() == "th") ? 1 : 0;
  374.         break;
  375.     }
  376.  
  377.     gDialog.CellHAlignCheckbox.checked = AdvancedEditUsed &&
  378.       previousIndex != gDialog.CellHAlignList.selectedIndex;
  379.  
  380.     previousIndex = gDialog.CellStyleList.selectedIndex;
  381.     gDialog.CellStyleList.selectedIndex = (globalCellElement.nodeName.toLowerCase() == "th") ? 1 : 0;
  382.     gDialog.CellStyleCheckbox.checked = AdvancedEditUsed && previousIndex != gDialog.CellStyleList.selectedIndex;
  383.  
  384.     previousIndex = gDialog.TextWrapList.selectedIndex;
  385.     if (GetHTMLOrCSSStyleValue(globalCellElement, "nowrap", "white-space") == "nowrap")
  386.       gDialog.TextWrapList.selectedIndex = 1;
  387.     else
  388.       gDialog.TextWrapList.selectedIndex = 0;
  389.     gDialog.TextWrapCheckbox.checked = AdvancedEditUsed && previousIndex != gDialog.TextWrapList.selectedIndex;
  390.  
  391.     previousValue = CellColor;
  392.     CellColor = GetHTMLOrCSSStyleValue(globalCellElement, bgcolor, cssBackgroundColorStr);
  393.     CellColor = ConvertRGBColorIntoHEXColor(CellColor);
  394.     SetColor("cellBackgroundCW", CellColor);
  395.     gDialog.CellColorCheckbox.checked = AdvancedEditUsed && previousValue != CellColor;
  396.  
  397.     // We want to set this true in case changes came
  398.     //   from Advanced Edit dialog session (must assume something changed)
  399.     CellDataChanged = true;
  400.   }
  401. }
  402.  
  403. function GetCellData(rowIndex, colIndex)
  404. {
  405.   // Get actual rowspan and colspan
  406.   var startRowIndexObj = new Object;
  407.   var startColIndexObj = new Object;
  408.   var rowSpanObj = new Object;
  409.   var colSpanObj = new Object;
  410.   var actualRowSpanObj = new Object;
  411.   var actualColSpanObj = new Object;
  412.   var isSelectedObj = new Object;
  413.   if (!cellData)
  414.     cellData = new Object;
  415.  
  416.   try {
  417.     cellData.cell =
  418.       editorShell.GetCellDataAt(TableElement, rowIndex, colIndex,
  419.                                 startRowIndexObj, startColIndexObj,
  420.                                 rowSpanObj, colSpanObj,
  421.                                 actualRowSpanObj, actualColSpanObj, isSelectedObj);
  422.     // We didn't find a cell
  423.     if (!cellData.cell) return false;
  424.   }
  425.   catch(ex) {
  426.     return false;
  427.   }
  428.  
  429.   cellData.startRowIndex = startRowIndexObj.value;
  430.   cellData.startColIndex = startColIndexObj.value;
  431.   cellData.rowSpan = rowSpanObj.value;
  432.   cellData.colSpan = colSpanObj.value;
  433.   cellData.actualRowSpan = actualRowSpanObj.value;
  434.   cellData.actualColSpan = actualColSpanObj.value;
  435.   cellData.isSelected = isSelectedObj.value;
  436.   return true;
  437. }
  438.  
  439. function SelectTableTab()
  440. {
  441.   globalElement = globalTableElement;
  442.   currentPanel = TablePanel;
  443. }
  444.  
  445. function SelectCellTab()
  446. {
  447.   globalElement = globalCellElement;
  448.   currentPanel = CellPanel;
  449. }
  450.  
  451. function SelectCellHAlign()
  452. {
  453.   SetCheckbox("CellHAlignCheckbox");
  454.   // Once user changes the alignment,
  455.   //  we loose their original "CharAt" alignment"
  456.   alignWasChar = false;
  457. }
  458.  
  459. function GetColorAndUpdate(ColorWellID)
  460. {
  461.   var colorWell = document.getElementById(ColorWellID);
  462.   if (!colorWell) return;
  463.  
  464.   var colorObj = new Object;
  465.  
  466.   switch( ColorWellID )
  467.   {
  468.     case "tableBackgroundCW":
  469.       colorObj.Type = "Table";
  470.       colorObj.TableColor = TableColor;
  471.       break;
  472.     case "cellBackgroundCW":
  473.       colorObj.Type = "Cell";
  474.       colorObj.CellColor = CellColor;
  475.       break;
  476.   }
  477.   // Avoid the JS warning
  478.   colorObj.NoDefault = false;
  479.   window.openDialog("chrome://editor/content/EdColorPicker.xul", "_blank", "chrome,close,titlebar,modal", "", colorObj);
  480.  
  481.   // User canceled the dialog
  482.   if (colorObj.Cancel)
  483.     return;
  484.  
  485.   switch( ColorWellID )
  486.   {
  487.     case "tableBackgroundCW":
  488.       TableColor = colorObj.BackgroundColor;
  489.       SetColor(ColorWellID, TableColor);
  490.       break;
  491.     case "cellBackgroundCW":
  492.       CellColor = colorObj.BackgroundColor;
  493.       SetColor(ColorWellID, CellColor);
  494.       SetCheckbox('CellColorCheckbox');
  495.       break;
  496.   }
  497. }
  498.  
  499. function SetColor(ColorWellID, color)
  500. {
  501.   // Save the color
  502.   if (ColorWellID == "cellBackgroundCW")
  503.   {
  504.     if (color)
  505.     {
  506.       globalCellElement.setAttribute(bgcolor, color);
  507.       gDialog.CellInheritColor.setAttribute("collapsed","true");
  508.     }
  509.     else
  510.     {
  511.       globalCellElement.removeAttribute(bgcolor);
  512.       // Reveal addition message explaining "default" color
  513.       gDialog.CellInheritColor.removeAttribute("collapsed");
  514.     }
  515.   }
  516.   else
  517.   {
  518.     if (color)
  519.     {
  520.       globalTableElement.setAttribute(bgcolor, color);
  521.       gDialog.TableInheritColor.setAttribute("collapsed","true");
  522.     }
  523.     else
  524.     {
  525.       globalTableElement.removeAttribute(bgcolor);
  526.       gDialog.TableInheritColor.removeAttribute("collapsed");
  527.     }
  528.     SetCheckbox('CellColorCheckbox');
  529.   }
  530.  
  531.   setColorWell(ColorWellID, color);
  532. }
  533.  
  534. function ChangeSelectionToFirstCell()
  535. {
  536.   if (!GetCellData(0,0))
  537.   {
  538.     dump("Can't find first cell in table!\n");
  539.     return;
  540.   }
  541.   CellElement = cellData.cell;
  542.   globalCellElement = CellElement;
  543.   globalElement = CellElement;
  544.  
  545.   curRowIndex = 0;
  546.   curColIndex = 0;
  547.   ChangeSelection(RESET_SELECTION);
  548. }
  549.  
  550. function ChangeSelection(newType)
  551. {
  552.   newType = Number(newType);
  553.  
  554.   if (SelectedCellsType == newType)
  555.     return;
  556.  
  557.   if (newType == RESET_SELECTION)
  558.     // Restore selection to existing focus cell
  559.     selection.collapse(CellElement,0);
  560.   else
  561.     SelectedCellsType = newType;
  562.  
  563.   // Keep the same focus CellElement, just change the type
  564.   DoCellSelection();
  565.   SetSelectionButtons();
  566.  
  567.   // Note: globalCellElement should still be a clone of CellElement
  568. }
  569.  
  570. function MoveSelection(forward)
  571. {
  572.   var newRowIndex = curRowIndex;
  573.   var newColIndex = curColIndex;
  574.   var focusCell;
  575.   var inRow = false;
  576.  
  577.   if (SelectedCellsType == SELECT_ROW)
  578.   {
  579.     newRowIndex += (forward ? 1 : -1);
  580.  
  581.     // Wrap around if before first or after last row
  582.     if (newRowIndex < 0)
  583.       newRowIndex = lastRowIndex;
  584.     else if (newRowIndex > lastRowIndex)
  585.       newRowIndex = 0;
  586.     inRow = true;
  587.  
  588.     // Use first cell in row for focus cell
  589.     newColIndex = 0;
  590.   }
  591.   else
  592.   {
  593.     // Cell or column:
  594.     if (!forward)
  595.       newColIndex--;
  596.  
  597.     if (SelectedCellsType == SELECT_CELL)
  598.     {
  599.       // Skip to next cell
  600.       if (forward)
  601.         newColIndex += curColSpan;
  602.     }
  603.     else  // SELECT_COLUMN
  604.     {
  605.       // Use first cell in column for focus cell
  606.       newRowIndex = 0;
  607.  
  608.       // Don't skip by colspan,
  609.       //  but find first cell in next cellmap column
  610.       if (forward)
  611.         newColIndex++;
  612.     }
  613.  
  614.     if (newColIndex < 0)
  615.     {
  616.       // Request is before the first cell in column
  617.  
  618.       // Wrap to last cell in column
  619.       newColIndex = lastColIndex;
  620.  
  621.       if (SelectedCellsType == SELECT_CELL)
  622.       {
  623.         // If moving by cell, also wrap to previous...
  624.         if (newRowIndex > 0)
  625.           newRowIndex -= 1;
  626.         else
  627.           // ...or the last row
  628.           newRowIndex = lastRowIndex;
  629.  
  630.         inRow = true;
  631.       }
  632.     }
  633.     else if (newColIndex > lastColIndex)
  634.     {
  635.       // Request is after the last cell in column
  636.  
  637.       // Wrap to first cell in column
  638.       newColIndex = 0;
  639.  
  640.       if (SelectedCellsType == SELECT_CELL)
  641.       {
  642.         // If moving by cell, also wrap to next...
  643.         if (newRowIndex < lastRowIndex)
  644.           newRowIndex++;
  645.         else
  646.           // ...or the first row
  647.           newRowIndex = 0;
  648.  
  649.         inRow = true;
  650.       }
  651.     }
  652.   }
  653.  
  654.   // Get the cell at the new location
  655.   do {
  656.     if (!GetCellData(newRowIndex, newColIndex))
  657.     {
  658.       dump("MoveSelection: CELL NOT FOUND\n");
  659.       return;
  660.     }
  661.     if (inRow)
  662.     {
  663.       if (cellData.startRowIndex == newRowIndex)
  664.         break;
  665.       else
  666.         // Cell spans from a row above, look for the next cell in row
  667.         newRowIndex += cellData.actualRowSpan;
  668.     }
  669.     else
  670.     {
  671.       if (cellData.startColIndex == newColIndex)
  672.         break;
  673.       else
  674.         // Cell spans from a Col above, look for the next cell in column
  675.         newColIndex += cellData.actualColSpan;
  676.     }
  677.   }
  678.   while(true);
  679.  
  680.   // Save data for current selection before changing
  681.   if (CellDataChanged) // && gDialog.ApplyBeforeMove.checked)
  682.   {
  683.     if (!ValidateCellData())
  684.       return;
  685.  
  686.     editorShell.BeginBatchChanges();
  687.     // Apply changes to all selected cells
  688.     ApplyCellAttributes();
  689.     editorShell.EndBatchChanges();
  690.  
  691.     SetCloseButton();
  692.   }
  693.  
  694.   // Set cell and other data for new selection
  695.   CellElement = cellData.cell;
  696.  
  697.   // Save globals for new current cell
  698.   curRowIndex = cellData.startRowIndex;
  699.   curColIndex = cellData.startColIndex;
  700.   curColSpan = cellData.actualColSpan;
  701.  
  702.   // Copy for new global cell
  703.   globalCellElement = CellElement.cloneNode(false);
  704.   globalElement = globalCellElement;
  705.  
  706.   // Change the selection
  707.   DoCellSelection();
  708.  
  709.   // Scroll page so new selection is visible
  710.   // Using SELECTION_ANCHOR_REGION makes the upper-left corner of first selected cell
  711.   //    the point to bring into view.
  712.   var selectionController = editorShell.selectionController;
  713.   if (selectionController)
  714.     selectionController.scrollSelectionIntoView(selectionController.SELECTION_NORMAL, selectionController.SELECTION_ANCHOR_REGION);
  715.  
  716.   // Reinitialize dialog using new cell
  717. //  if (!gDialog.KeepCurrentData.checked)
  718.   // Setting this false unchecks all "set attributes" checkboxes
  719.   AdvancedEditUsed = false;
  720.   InitCellPanel();
  721.   AdvancedEditUsed = true;
  722. }
  723.  
  724.  
  725. function DoCellSelection()
  726. {
  727.   // Collapse selection into to the focus cell
  728.   //  so editor uses that as start cell
  729.   selection.collapse(CellElement, 0);
  730.  
  731.   switch (SelectedCellsType)
  732.   {
  733.     case SELECT_CELL:
  734.       editorShell.SelectTableCell();
  735.       break
  736.     case SELECT_ROW:
  737.       editorShell.SelectTableRow();
  738.       break;
  739.     default:
  740.       editorShell.SelectTableColumn();
  741.       break;
  742.   }
  743.   // Get number of cells selected
  744.   var tagNameObj = new Object;
  745.   var countObj = new Object;
  746.   tagNameObj.value = "";
  747.   var tableOrCellElement = editorShell.GetSelectedOrParentTableElement(tagNameObj, countObj);
  748.   if (tagNameObj.value == "td")
  749.     gSelectedCellCount = countObj.value;
  750.   else
  751.     gSelectedCellCount = 0;
  752.  
  753.   // Currently, we can only allow advanced editing on ONE cell element at a time
  754.   //   else we ignore CSS, JS, and HTML attributes not already in dialog
  755.   SetElementEnabledById("AdvancedEditButton2", gSelectedCellCount == 1);
  756. }
  757.  
  758. function SetSelectionButtons()
  759. {
  760.   if (SelectedCellsType == SELECT_ROW)
  761.   {
  762.     // Trigger CSS to set images of up and down arrows
  763.     gDialog.PreviousButton.setAttribute("type","row");
  764.     gDialog.NextButton.setAttribute("type","row");
  765.   }
  766.   else
  767.   {
  768.     // or images of left and right arrows
  769.     gDialog.PreviousButton.setAttribute("type","col");
  770.     gDialog.NextButton.setAttribute("type","col");
  771.   }
  772.   DisableSelectionButtons((SelectedCellsType == SELECT_ROW && rowCount == 1) ||
  773.                           (SelectedCellsType == SELECT_COLUMN && colCount == 1) ||
  774.                           (rowCount == 1 && colCount == 1));
  775. }
  776.  
  777. function DisableSelectionButtons( disable )
  778. {
  779.   gDialog.PreviousButton.setAttribute("disabled", disable ? "true" : "false");
  780.   gDialog.NextButton.setAttribute("disabled", disable ? "true" : "false");
  781. }
  782.  
  783. function SwitchToValidatePanel()
  784. {
  785.   if (currentPanel != validatePanel)
  786.   {
  787.     //Set index for starting panel on the <tabpanels> element
  788.     gDialog.TabPanels.selectedIndex = validatePanel; //setAttribute("selectedIndex", validatePanel);
  789.     if (validatePanel == CellPanel)
  790.     {
  791.       // Trigger setting of style for the tab widgets
  792.       gDialog.CellTab.selected = "true";
  793.       gDialog.TableTab.selected = null;
  794.     } else {
  795.       gDialog.TableTab.selected = "true";
  796.       gDialog.CellTab.selected = null;
  797.     }
  798.     currentPanel = validatePanel;
  799.   }
  800. }
  801.  
  802. function SetAlign(listID, defaultValue, element, attName)
  803. {
  804.   var value = document.getElementById(listID).selectedItem.value;
  805.   if (value == defaultValue)
  806.     element.removeAttribute(attName);
  807.   else
  808.     element.setAttribute(attName, value);
  809. }
  810.  
  811. function ValidateTableData()
  812. {
  813.   validatePanel = TablePanel;
  814.   newRowCount = Number(ValidateNumber(gDialog.TableRowsInput, null, 1, maxRows, null, true, true));
  815.   if (gValidationError) return false;
  816.  
  817.   newColCount = Number(ValidateNumber(gDialog.TableColumnsInput, null, 1, maxColumns, null, true, true));
  818.   if (gValidationError) return false;
  819.  
  820.   // If user is deleting any cells, get confirmation
  821.   // (This is a global to the dialog and we ask only once per dialog session)
  822.   if ( !canDelete &&
  823.         (newRowCount < rowCount ||
  824.          newColCount < colCount) ) 
  825.   {
  826.     if (ConfirmWithTitle(GetString("DeleteTableTitle"), 
  827.                          GetString("DeleteTableMsg"),
  828.                          GetString("DeleteCells")) )
  829.     {
  830.       canDelete = true;
  831.     }
  832.     else
  833.     {
  834.       SetTextboxFocus(newRowCount < rowCount ? gDialog.TableRowsInput : gDialog.TableColumnsInput);
  835.       return false;
  836.     }
  837.   }
  838.  
  839.   ValidateNumber(gDialog.TableWidthInput, gDialog.TableWidthUnits,
  840.                  1, maxPixels, globalTableElement, "width");
  841.   if (gValidationError) return false;
  842.  
  843.   if (gUseCSS) {
  844.     ValidateNumber(gDialog.TableHeightInput, gDialog.TableHeightUnits,
  845.                    1, maxPixels, globalTableElement, "height");
  846.     if (gValidationError) return false;
  847.   }
  848.  
  849.   var border = ValidateNumber(gDialog.BorderWidthInput, null, 0, maxPixels, globalTableElement, "border");
  850.   // TODO: Deal with "BORDER" without value issue
  851.   if (gValidationError) return false;
  852.  
  853.   ValidateNumber(gDialog.SpacingInput, null, 0, maxPixels, globalTableElement, "cellspacing");
  854.   if (gValidationError) return false;
  855.  
  856.   ValidateNumber(gDialog.PaddingInput, null, 0, maxPixels, globalTableElement, "cellpadding");
  857.   if (gValidationError) return false;
  858.  
  859.   SetAlign("TableAlignList", defHAlign, globalTableElement, "align");
  860.  
  861.   // Color is set on globalCellElement immediately
  862.   return true;
  863. }
  864.  
  865. function ValidateCellData()
  866. {
  867.  
  868.   validatePanel = CellPanel;
  869.  
  870.   if (gDialog.CellHeightCheckbox.checked)
  871.   {
  872.     ValidateNumber(gDialog.CellHeightInput, gDialog.CellHeightUnits,
  873.                     1, maxPixels, globalCellElement, "height");
  874.     if (gValidationError) return false;
  875.   }
  876.  
  877.   if (gDialog.CellWidthCheckbox.checked)
  878.   {
  879.     ValidateNumber(gDialog.CellWidthInput, gDialog.CellWidthUnits,
  880.                    1, maxPixels, globalCellElement, "width");
  881.     if (gValidationError) return false;
  882.   }
  883.  
  884.   if (gDialog.CellHAlignCheckbox.checked)
  885.   {
  886.     var hAlign = gDialog.CellHAlignList.selectedItem.value;
  887.  
  888.     // Horizontal alignment is complicated by "char" type
  889.     // We don't change current values if user didn't edit alignment
  890.     if (!alignWasChar)
  891.     {
  892.       globalCellElement.removeAttribute(charStr);
  893.  
  894.       // Always set "align" attribute,
  895.       //  so the default "left" is effective in a cell
  896.       //  when parent row has align set.
  897.       globalCellElement.setAttribute("align", hAlign);
  898.     }
  899.   }
  900.  
  901.   if (gDialog.CellVAlignCheckbox.checked)
  902.   {
  903.     // Always set valign (no default in 2nd param) so
  904.     //  the default "middle" is effective in a cell
  905.     //  when parent row has valign set.
  906.     SetAlign("CellVAlignList", "", globalCellElement, "valign");
  907.   }
  908.  
  909.   if (gDialog.TextWrapCheckbox.checked)
  910.   {
  911.     if (gDialog.TextWrapList.selectedIndex == 1)
  912.       globalCellElement.setAttribute("nowrap","true");
  913.     else
  914.       globalCellElement.removeAttribute("nowrap");
  915.   }
  916.  
  917.   return true;
  918. }
  919.  
  920. function ValidateData()
  921. {
  922.   var result;
  923.   var savePanel = currentPanel;
  924.  
  925.   // Validate current panel first
  926.   if (currentPanel == TablePanel)
  927.   {
  928.     result = ValidateTableData();
  929.     if (result)
  930.       result = ValidateCellData();
  931.   } else {
  932.     result = ValidateCellData();
  933.     if (result)
  934.       result = ValidateTableData();
  935.   }
  936.   if(!result) return false;
  937.  
  938.   // If we passed, restore former currentPanel
  939.   currentPanel = savePanel;
  940.  
  941.   // Set global element for AdvancedEdit
  942.   if(currentPanel == TablePanel)
  943.     globalElement = globalTableElement;
  944.   else
  945.     globalElement = globalCellElement;
  946.  
  947.   return true;
  948. }
  949.  
  950. function ChangeCellTextbox(textboxID)
  951. {
  952.   // Filter input for just integers
  953.   forceInteger(textboxID);
  954.  
  955.   if (currentPanel == CellPanel)
  956.     CellDataChanged = true;
  957. }
  958.  
  959. // Call this when a textbox or menulist is changed
  960. //   so the checkbox is automatically set
  961. function SetCheckbox(checkboxID)
  962. {
  963.   if (checkboxID && checkboxID.length > 0)
  964.   {
  965.     // Set associated checkbox
  966.     document.getElementById(checkboxID).checked = true;
  967.   }
  968.   CellDataChanged = true;
  969. }
  970.  
  971. function ChangeIntTextbox(textboxID, checkboxID)
  972. {
  973.   // Filter input for just integers
  974.   forceInteger(textboxID);
  975.  
  976.   // Set associated checkbox
  977.   SetCheckbox(checkboxID);
  978. }
  979.  
  980. function CloneAttribute(destElement, srcElement, attr)
  981. {
  982.   var value = srcElement.getAttribute(attr);
  983.   // Use editorShell methods since we are always
  984.   //  modifying a table in the document and
  985.   //  we need transaction system for undo
  986.   if (!value || value.length == 0)
  987.     editorShell.RemoveAttribute(destElement, attr);
  988.   else
  989.     editorShell.SetAttribute(destElement, attr, value);
  990. }
  991.  
  992. function ApplyTableAttributes()
  993. {
  994.   var newAlign = gDialog.TableCaptionList.selectedItem.value;
  995.   if (!newAlign) newAlign = "";
  996.  
  997.   if (TableCaptionElement)
  998.   {
  999.     // Get current alignment
  1000.     var align = TableCaptionElement.align.toLowerCase();
  1001.     // This is the default
  1002.     if (!align) align = "top";
  1003.  
  1004.     if (newAlign == "")
  1005.     {
  1006.       // Remove existing caption
  1007.       editorShell.DeleteElement(TableCaptionElement);
  1008.       TableCaptionElement = null;
  1009.     }
  1010.     else if( align != newAlign)
  1011.     {
  1012.       if (align == "top") // This is default, so don't explicitly set it
  1013.         editorShell.RemoveAttribute(TableCaptionElement, "align");
  1014.       else
  1015.         editorShell.SetAttribute(TableCaptionElement, "align", newAlign);
  1016.     }
  1017.   }
  1018.   else if (newAlign != "")
  1019.   {
  1020.     // Create and insert a caption:
  1021.     TableCaptionElement = editorShell.CreateElementWithDefaults("caption");
  1022.     if (TableCaptionElement)
  1023.     {
  1024.       if (newAlign != "top")
  1025.         TableCaptionElement.setAttribute("align", newAlign);
  1026.  
  1027.       // Insert it into the table - caption is always inserted as first child
  1028.       editorShell.InsertElement(TableCaptionElement, TableElement, 0, true);
  1029.  
  1030.       // Put selecton back where it was
  1031.       ChangeSelection(RESET_SELECTION);
  1032.     }
  1033.   }
  1034.  
  1035.   var countDelta;
  1036.   var foundcell;
  1037.   var i;
  1038.  
  1039.   if (newRowCount != rowCount)
  1040.   {
  1041.     countDelta = newRowCount - rowCount;
  1042.     if (newRowCount > rowCount)
  1043.     {
  1044.       // Append new rows
  1045.       // Find first cell in last row
  1046.       if(GetCellData(lastRowIndex, 0))
  1047.       {
  1048.         try {
  1049.           // Move selection to the last cell
  1050.           selection.collapse(cellData.cell,0);
  1051.           // Insert new rows after it
  1052.           editorShell.InsertTableRow(countDelta, true);
  1053.           rowCount = newRowCount;
  1054.           lastRowIndex = rowCount - 1;
  1055.           // Put selecton back where it was
  1056.           ChangeSelection(RESET_SELECTION);
  1057.         }
  1058.         catch(ex) {
  1059.           dump("FAILED TO FIND FIRST CELL IN LAST ROW\n");
  1060.         }
  1061.       }
  1062.     }
  1063.     else
  1064.     {
  1065.       // Delete rows
  1066.       if (canDelete)
  1067.       {
  1068.         // Find first cell starting in first row we delete
  1069.         var firstDeleteRow = rowCount + countDelta;
  1070.         foundCell = false;
  1071.         for ( i = 0; i <= lastColIndex; i++)
  1072.         {
  1073.           if (!GetCellData(firstDeleteRow, i))
  1074.             break; // We failed to find a cell
  1075.  
  1076.           if (cellData.startRowIndex == firstDeleteRow)
  1077.           {
  1078.             foundCell = true;
  1079.             break;
  1080.           }
  1081.         };
  1082.         if (foundCell)
  1083.         {
  1084.           try {
  1085.             // Move selection to the cell we found
  1086.             selection.collapse(cellData.cell, 0);
  1087.             editorShell.DeleteTableRow(-countDelta);
  1088.             rowCount = newRowCount;
  1089.             lastRowIndex = rowCount - 1;
  1090.             if (curRowIndex > lastRowIndex)
  1091.               // We are deleting our selection
  1092.               // move it to start of table
  1093.               ChangeSelectionToFirstCell()
  1094.             else
  1095.               // Put selecton back where it was
  1096.               ChangeSelection(RESET_SELECTION);
  1097.           }
  1098.           catch(ex) {
  1099.             dump("FAILED TO FIND FIRST CELL IN LAST ROW\n");
  1100.           }
  1101.         }
  1102.       }
  1103.     }
  1104.   }
  1105.  
  1106.   if (newColCount != colCount)
  1107.   {
  1108.     countDelta = newColCount - colCount;
  1109.  
  1110.     if (newColCount > colCount)
  1111.     {
  1112.       // Append new columns
  1113.       // Find last cell in first column
  1114.       if(GetCellData(0, lastColIndex))
  1115.       {
  1116.         try {
  1117.           // Move selection to the last cell
  1118.           selection.collapse(cellData.cell,0);
  1119.           editorShell.InsertTableColumn(countDelta, true);
  1120.           colCount = newColCount;
  1121.           lastColIndex = colCount-1;
  1122.           // Restore selection
  1123.           ChangeSelection(RESET_SELECTION);
  1124.         }
  1125.         catch(ex) {
  1126.           dump("FAILED TO FIND FIRST CELL IN LAST COLUMN\n");
  1127.         }
  1128.       }
  1129.     }
  1130.     else
  1131.     {
  1132.       // Delete columns
  1133.       if (canDelete)
  1134.       {
  1135.         var firstDeleteCol = colCount + countDelta;
  1136.         foundCell = false;
  1137.         for ( i = 0; i <= lastRowIndex; i++)
  1138.         {
  1139.           // Find first cell starting in first column we delete
  1140.           if (!GetCellData(i, firstDeleteCol))
  1141.             break; // We failed to find a cell
  1142.  
  1143.           if (cellData.startColIndex == firstDeleteCol)
  1144.           {
  1145.             foundCell = true;
  1146.             break;
  1147.           }
  1148.         };
  1149.         if (foundCell)
  1150.         {
  1151.           try {
  1152.             // Move selection to the cell we found
  1153.             selection.collapse(cellData.cell, 0);
  1154.             editorShell.DeleteTableColumn(-countDelta);
  1155.             colCount = newColCount;
  1156.             lastColIndex = colCount-1;
  1157.             if (curColIndex > lastColIndex)
  1158.               ChangeSelectionToFirstCell()
  1159.             else
  1160.               ChangeSelection(RESET_SELECTION);
  1161.           }
  1162.           catch(ex) {
  1163.             dump("FAILED TO FIND FIRST CELL IN LAST ROW\n");
  1164.           }
  1165.         }
  1166.       }
  1167.     }
  1168.   }
  1169.  
  1170.   // Clone all remaining attributes to pick up
  1171.   //  anything changed by Advanced Edit Dialog
  1172.   editorShell.CloneAttributes(TableElement, globalTableElement);
  1173. }
  1174.  
  1175. function ApplyCellAttributes()
  1176. {
  1177.   var selectedCell = editorShell.GetFirstSelectedCell();
  1178.   if (!selectedCell)
  1179.     return;
  1180.  
  1181.   if (gSelectedCellCount == 1)
  1182.   {
  1183.     // When only one cell is selected, simply clone entire element,
  1184.     //  thus CSS and JS from Advanced edit is copied
  1185.     editorShell.CloneAttributes(selectedCell, globalCellElement);
  1186.  
  1187.     if (gDialog.CellStyleCheckbox.checked)
  1188.     {
  1189.       var currentStyleIndex = (selectedCell.nodeName.toLowerCase() == "th") ? 1 : 0;
  1190.       if (gDialog.CellStyleList.selectedIndex != currentStyleIndex)
  1191.       {
  1192.         // Switch cell types
  1193.         // (replaces with new cell and copies attributes and contents)
  1194.         selectedCell = editorShell.SwitchTableCellHeaderType(selectedCell);
  1195.       }
  1196.     }
  1197.   }
  1198.   else
  1199.   {
  1200.     // Apply changes to all selected cells
  1201.     //XXX THIS DOESN'T COPY ADVANCED EDIT CHANGES!
  1202.     while (selectedCell)
  1203.     {
  1204.       ApplyAttributesToOneCell(selectedCell);
  1205.       selectedCell = editorShell.GetNextSelectedCell();
  1206.     }
  1207.   }
  1208.   CellDataChanged = false;
  1209. }
  1210.  
  1211. function ApplyAttributesToOneCell(destElement)
  1212. {
  1213.   if (gDialog.CellHeightCheckbox.checked)
  1214.     CloneAttribute(destElement, globalCellElement, "height");
  1215.  
  1216.   if (gDialog.CellWidthCheckbox.checked)
  1217.     CloneAttribute(destElement, globalCellElement, "width");
  1218.  
  1219.   if (gDialog.CellHAlignCheckbox.checked)
  1220.   {
  1221.     CloneAttribute(destElement, globalCellElement, "align");
  1222.     CloneAttribute(destElement, globalCellElement, charStr);
  1223.   }
  1224.  
  1225.   if (gDialog.CellVAlignCheckbox.checked)
  1226.     CloneAttribute(destElement, globalCellElement, "valign");
  1227.  
  1228.   if (gDialog.TextWrapCheckbox.checked)
  1229.     CloneAttribute(destElement, globalCellElement, "nowrap");
  1230.  
  1231.   if (gDialog.CellStyleCheckbox.checked)
  1232.   {
  1233.     var newStyleIndex = gDialog.CellStyleList.selectedIndex;
  1234.     var currentStyleIndex = (destElement.nodeName.toLowerCase() == "th") ? 1 : 0;
  1235.  
  1236.     if (newStyleIndex != currentStyleIndex)
  1237.     {
  1238.       // Switch cell types
  1239.       // (replaces with new cell and copies attributes and contents)
  1240.       destElement = editorShell.SwitchTableCellHeaderType(destElement);
  1241.     }
  1242.   }
  1243.  
  1244.   if (gDialog.CellColorCheckbox.checked)
  1245.     CloneAttribute(destElement, globalCellElement, "bgcolor");
  1246. }
  1247.  
  1248. function SetCloseButton()
  1249. {
  1250.   // Change text on "Cancel" button after Apply is used
  1251.   if (!ApplyUsed)
  1252.   {
  1253.     document.getElementById("cancel").setAttribute("label",GetString("Close"));
  1254.     ApplyUsed = true;
  1255.   }
  1256. }
  1257.  
  1258. function onApply()
  1259. {
  1260.   Apply();
  1261.   return false; // don't close window
  1262. }
  1263.  
  1264. function Apply()
  1265. {
  1266.   if (ValidateData())
  1267.   {
  1268.     editorShell.BeginBatchChanges();
  1269.  
  1270.     ApplyTableAttributes();
  1271.  
  1272.     // We may have just a table, so check for cell element
  1273.     if (globalCellElement)
  1274.       ApplyCellAttributes();
  1275.  
  1276.     editorShell.EndBatchChanges();
  1277.  
  1278.     SetCloseButton();
  1279.     return true;
  1280.   }
  1281.   return false;
  1282. }
  1283.  
  1284. function doHelpButton()
  1285. {
  1286.   openHelp("table_properties");
  1287. }
  1288.  
  1289. function onAccept()
  1290. {
  1291.   // Do same as Apply and close window if ValidateData succeeded
  1292.   var retVal = Apply();
  1293.   if (retVal)
  1294.     SaveWindowLocation();
  1295.  
  1296.   return retVal;
  1297. }
  1298.